import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:website.core/core/presentation/utils/markdown_parser.dart';

Text buildMarkdown({
  required String markdown,
  required TextStyle textStyle,
  required TextAlign textAlign,
  required BuildContext context,
  double? textScaleFactor,
  TextWidthBasis? textWidthBasis,
  TextStyle? strongTextStyle,
  TextStyle? linkTextStyle,
  void Function({required String href})? onLinkPressed,
  TextStyle? markedTextStyle,
  TextStyle? emphasisedTextStyle,
}) {
  final nodes = parseMarkdown(markdown);

  final textSpans = <TextSpan>[];

  for (final node in nodes) {
    final nodeTextSpans = _buildNode(
      node: node,
      textStyle: textStyle,
      context: context,
      strongTextStyle: strongTextStyle,
      linkTextStyle: linkTextStyle,
      onLinkPressed: onLinkPressed,
      markedTextStyle: markedTextStyle,
      emphasisedTextStyle: emphasisedTextStyle,
    );

    textSpans.addAll(nodeTextSpans);
  }

  final textWidget = Text.rich(
    TextSpan(
      children: textSpans,
    ),
    textAlign: textAlign,
    textScaleFactor: textScaleFactor,
    textWidthBasis: textWidthBasis,
  );

  return textWidget;
}

List<TextSpan> _buildNode({
  required md.Node node,
  required TextStyle textStyle,
  required BuildContext context,
  TextStyle? strongTextStyle,
  TextStyle? linkTextStyle,
  void Function({required String href})? onLinkPressed,
  TextStyle? markedTextStyle,
  TextStyle? emphasisedTextStyle,
  void Function()? onPressed,
}) {
  if (node is md.Text) {
    GestureRecognizer? recognizer;

    if (onPressed != null) {
      recognizer = TapGestureRecognizer()..onTap = onPressed;
    }

    return [
      TextSpan(
        text: node.text,
        style: textStyle,
        recognizer: recognizer,
      ),
    ];
  }

  if (node is md.Element) {
    var updatedTextStyle = textStyle;
    var updatedOnPressed = onPressed;

    if (node.tag == 'strong') {
      updatedTextStyle = textStyle.merge(strongTextStyle);
    } else if (node.tag == 'a') {
      updatedTextStyle = textStyle.merge(linkTextStyle);

      final href = node.attributes['href'] as String;

      if (onLinkPressed != null) {
        updatedOnPressed = () {
          onLinkPressed(
            href: href,
          );
        };
      }
    } else if (node.tag == 'mark') {
      updatedTextStyle = textStyle.merge(markedTextStyle);
    } else if (node.tag == 'em') {
      updatedTextStyle = textStyle.merge(emphasisedTextStyle);
    }

    final textSpans = <TextSpan>[];

    for (final child in node.children!) {
      final childTextSpans = _buildNode(
        node: child,
        textStyle: updatedTextStyle,
        context: context,
        onLinkPressed: onLinkPressed,
        onPressed: updatedOnPressed,
        strongTextStyle: strongTextStyle,
        linkTextStyle: linkTextStyle,
        markedTextStyle: markedTextStyle,
        emphasisedTextStyle: emphasisedTextStyle,
      );

      textSpans.addAll(childTextSpans);
    }

    return textSpans;
  }

  throw UnimplementedError();
}
